package com.tsl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cqgc.entity.User;
import com.cqgc.mapper.UserMapper;
import com.cqgc.service.UserService;
import com.tsl.domain.dto.PageDto;
import com.tsl.domain.dto.TbSKUDto;
import com.tsl.domain.pojo.RedisPage;
import com.tsl.domain.pojo.TbSKU;
import com.tsl.domain.vo.PageVo;
import com.tsl.exception.ProductionException;
import com.tsl.exception.SelectByIdException;
import com.tsl.mapper.TbProductMapper;
import com.tsl.service.ITbProductService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品信息表 服务实现类
 * </p>
 *
 * @author 唐书亮
 * @since 2024-04-17
 */
@Service
public class TbProductServiceImpl extends ServiceImpl<TbProductMapper, TbSKU> implements ITbProductService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    TbProductMapper productMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    UserService userService;
    private String prefix="productManagement";
    //创建实体,方便后续封装key和value
    RedisPage redis = new RedisPage();
    @Override
    public Boolean updateProduct(TbSKU tbSKU) {
        String key = prefix+"_"+tbSKU.getPid();
        if (ObjectUtils.isEmpty(tbSKU)) {
            throw new ProductionException("更新实体为空");
        }

        boolean isUpdate = this.updateById(tbSKU);
        //更新成功就修改redis里存放的数据
        if (isUpdate) {
            //先把redis缓存里的删除了
            redisTemplate.delete(redis.getKey());
            //增加修改的数据
            redisTemplate.opsForValue().set(key, tbSKU, 30l, TimeUnit.MINUTES);
        }
        return isUpdate;
    }

    @Override
    public TbSKU selectById(Integer id) {
        TbSKU byId ;
        String key = prefix+"_"+id;
        //从缓存里查找
        byId = (TbSKU)redisTemplate.opsForValue().get(key);
        if (!ObjectUtils.isEmpty(byId)) {
            return byId;
        }
        //缓存没找到就从数据库找
        if (id > 0) {
            byId = this.getById(id);

            redisTemplate.opsForValue().set(key,byId,30,TimeUnit.MINUTES);
            return byId;
        }else{ throw new SelectByIdException("查询id不符合规范");}
    }

    @Override
    public Boolean deleteProduct(Integer id) {
        boolean isDelete = false; //删除是否成功的变量
        TbSKU tbSKU = null;//存储查询的结果
        if (id >0){
            //先查询商品是否以及被下单
            //先根据id查询商品数据,得到名称,将他从redis缓存里删除,在删除数据库的信息

            isDelete = productMapper.deleteById(id);

        }
        //删除成功就从redis里删除
        if (isDelete) {
            redisTemplate.delete(redis.getKey());
        }
        return isDelete;
    }


    //新增产品
    @Override
    public Boolean saveProduct(TbSKUDto tbSKUDto) {

        boolean save = false;//是否保存成功,默认失败
        TbSKU tbSKU =new TbSKU();
        BeanUtils.copyProperties(tbSKUDto,tbSKU);
        //1.设置商品的阶段默认为1(已上架) -1(已删除)  0(下架)
        tbSKU.setStep(1);
        tbSKU.setIsDelete(1);
        //根据用户名查询相应公司的id
        User byName = userService.findByName(tbSKU.getUsername());
        //从查询回来的数据里拿到uid并存入tbSKU里
        tbSKU.setUid(byName.getUid());
        if (ObjectUtils.isEmpty(tbSKU)){
            throw new ProductionException("商品信息不全,请填写正确");
        }else {
             save = this.save(tbSKU);
             //存入redis里
            String key = prefix+"_"+tbSKU.getPid();
            redisTemplate.delete(redis.getKey());
            redisTemplate.opsForValue().set(key,tbSKU,30l,TimeUnit.MINUTES);
        }
        return save;

    }
    //分页查询所有产品
    @Override
    public PageVo listPageProduct(PageDto pageDto) {
        /**
         * key是只有页数和大小的查询
         * allKey是查询带有商品名的分页查询
         * */
        String key =prefix+pageDto.getPage()+"_"+pageDto.getPageSize();
        String  allKey = prefix+pageDto.getPage()+"_"+pageDto.getPageSize()+pageDto.getProductName();
        Integer page;
        Integer pageSize;
        PageVo pageVo = new PageVo() ;
        PageVo pageVo1 = new PageVo();
        //对页码数据进行进行健壮性判断
        if (ObjectUtils.isEmpty(pageDto)) {
            page =1;
            pageSize =5;
        }else{
            page = pageDto.getPage();
            pageSize = pageDto.getPageSize();
        }
        //如果redis里有数据就直接返回,否则查询数据库
        if (pageDto.getProductName() == null && pageDto.getProductName() == ""){
            pageVo =(PageVo) redisTemplate.opsForValue().get(key);
        }
        if (org.apache.commons.lang3.ObjectUtils.allNotNull(pageVo, pageVo.getTotal(), pageVo.getTotalPage(), pageVo.getList())) {
            return pageVo;
        }
        Page<TbSKU>  pageList= new Page<>(page,pageSize);
        LambdaQueryWrapper<TbSKU> wrapper = new LambdaQueryWrapper();
        //当商品名存在时添加模糊查询的条件
        wrapper.likeLeft(pageDto.getProductName() != null && pageDto.getProductName() != "",TbSKU::getPname, pageDto.getProductName());

        //不查询已经删除的商品
        wrapper.eq(TbSKU::getIsDelete,1);
        Page<TbSKU> tbSKUPage = page(pageList,wrapper).addOrder(new OrderItem("price", true));
        //根据list里的uid查询具体用户名并且修改
        tbSKUPage.getRecords().stream().map(
            tbSKU ->{
                Integer uid = tbSKU.getUid();
                User user=userMapper.selectById(uid);
                tbSKU.setUsername(user.getUsername());
                return tbSKU;
            }
        ).collect(Collectors.toList());
        //将结果封装到PageVo里返回
        pageVo1.setList(tbSKUPage.getRecords());
        pageVo1.setTotal(tbSKUPage.getTotal());
        pageVo1.setTotalPage(tbSKUPage.getSize());

        redisTemplate.opsForValue().set(key,pageVo1,30l, TimeUnit.MINUTES);
        //封装key和value
        redis.setKey(key);
        redis.setValue(pageVo1);
        return pageVo1;
    }

    @Override
    public Boolean updateProductStateById(Integer id,Integer step) {
        //判断id是否符合标准
        if (id < 0){
            return false;
        }
        //根据id将产品的状态设置为step
        //2.1.通过LambdaUpdateWrapper进行条件构造
        LambdaUpdateWrapper<TbSKU> updateWrapper = new LambdaUpdateWrapper<>();
         updateWrapper.eq(TbSKU::getPid, id).set(TbSKU::getStep, step);
        //2.2执行wrapper
        boolean update = this.update(updateWrapper);

        //更新缓存里的数据
        if (update) {
            redisTemplate.delete(redis.getKey());
        }
        //返回数据
        return update;
    }
}
